package cn.com.idmy.base.util;

import cn.com.idmy.base.TreeNode;
import lombok.NonNull;
import org.dromara.hutool.core.collection.CollStreamUtil;
import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.split.SplitUtil;

import java.util.*;
import java.util.stream.Collectors;

public class TreeUtil {
    public static String treeNameSeparator = "/";
    public static long rootId = 0;

    /**
     * 将列表转换为树结构
     *
     * @param ins     要转换的列表
     * @param treePid 树的父节点ID
     * @param <T>     树节点的类型
     * @return 转换后的树结构
     */
    public static <T extends TreeNode<T>> List<T> listToTrees(List<T> ins, long treePid) {
        Assert.notEmpty(ins, "集合不能为空");
        var treeMap = CollStreamUtil.groupByKey(ins, T::getPid);
        for (var parentId : treeMap.keySet()) {
            var children = treeMap.get(parentId);
            for (var child : children) {
                child.setChildren(treeMap.get(child.getId()));
            }
        }
        return treeMap.get(treePid);
    }

    public static <T extends TreeNode<T>> List<T> listToTrees(List<T> ins) {
        return listToTrees(ins, rootId);
    }

    public static <T extends TreeNode<T>> T listToTree(List<T> ins, long treePid) {
        var ts = listToTrees(ins, treePid);
        Assert.isTrue(ts.size() == 1, "找到多棵树，请使用 listToTrees");
        return ts.getFirst();
    }

    public static <T extends TreeNode<T>> T listToTree(List<T> ins) {
        return listToTree(ins, rootId);
    }

    public static <T extends TreeNode<T>> void recursiveTree(List<T> trees) {
        Assert.notEmpty(trees, "树集合不能为空");
        for (var tree : trees) {
            tree.setLevel(tree.getLevel() == null ? 0 : tree.getLevel());
            recursiveTree(tree);
        }
    }

    /**
     * 递归处理树结构
     *
     * @param parent 父节点
     */
    public static <T extends TreeNode<T>> void recursiveTree(@NonNull T parent) {
        // 如果父节点的 ids 路径为空或与根节点的 id 相等，则设置 ids 路径和 names 路径
        if (StrUtil.isBlank(parent.getIdsPath()) || Objects.equals(parent.getPid(), rootId)) {
            parent.setIdsPath(joinPath("", parent.getId()));
            parent.setNamesPath(joinPath("", parent.getName()));
        }

        // 获取父节点的子节点
        List<T> children = parent.getChildren();
        if (children != null) {
            // 对子节点进行排序
            Collections.sort(children);
            // 遍历每个子节点
            for (var child : children) {
                // 设置子节点的层级
                child.setLevel(parent.getLevel() + 1);
                // 设置子节点的 ids 路径
                child.setIdsPath(joinPath(parent.getIdsPath(), child.getId()));
                // 设置子节点的 names 路径
                child.setNamesPath(joinPath(parent.getNamesPath(), child.getName()));

                // 如果子节点没有子节点，则设置为叶子节点
                if (child.getChildren() == null) {
                    child.setIsLeaf(Boolean.TRUE);
                } else {
                    // 如果子节点有子节点，则设置为非叶子节点
                    child.setIsLeaf(Boolean.FALSE);
                    // 递归处理子节点
                    recursiveTree(child);
                }
            }
        }
    }

    public static String joinPath(String path, Object val) {
        if (StrUtil.isBlank(path)) {
            return String.valueOf(val);
        } else {
            return path + treeNameSeparator + val;
        }
    }

    public static List<Long> idsPathToList(String var) {
        if (StrUtil.isBlank(var)) {
            return new ArrayList<>(1);
        } else {
            String[] strings = SplitUtil.splitToArray(var, treeNameSeparator);
            Long[] longs = ConvertUtil.toLongArray(strings);
            return Arrays.stream(longs).collect(Collectors.toList());
        }
    }

    public static List<String> namesPathToList(String val) {
        if (StrUtil.isBlank(val)) {
            return new ArrayList<>(1);
        } else {
            return Arrays.stream(val.split(treeNameSeparator)).collect(Collectors.toList());
        }
    }
}
